/*
 * KindlegenPanel.java
 *
 *  created: 7.10.2011
 *  charset: UTF-8
 *  license: MIT (X11) (See LICENSE file for full license)
 */
package cz.mp.k3bg.gui;


import static cz.mp.k3bg.Constants.*;
import static cz.mp.k3bg.Images.*;
import cz.mp.k3bg.*;
import static cz.mp.k3bg.TextSource.getLocText;
import cz.mp.k3bg.core.KindlegenRunner;
import cz.mp.k3bg.gui.component.FileChooserField;
import cz.mp.k3bg.gui.component.LabelForMandatory;
import cz.mp.k3bg.gui.component.LinkLabel;
import cz.mp.k3bg.log.LoggerManager;
import cz.mp.k3bg.util.DesktopUtils;
import cz.mp.util.GuiUtils;
import cz.mp.util.StringUtils;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;

/**
 * Panel pro definování příkazu {@code kindlegen} a pro spuštění
 * vytvoření knihy.
 * 
 * @author Martin Pokorný
 * @version 0.1
 * @see MainTabbedPane
 * @see KindlegenRunner
 * @see GenerateMobiDialog
 */
public class KindlegenPanel extends TabPanel {

    private static final boolean DEBUG = false;
    private static final Logger logger =
            LoggerManager.getLogger(KindlegenPanel.class, DEBUG);

    private ImageIcon IMG_EBOOK = Images.getImage(EBOOK_32);
    
    
    private JLabel outDirLabel = new LabelForMandatory(getLocText("gui.kindlegen.output_dir"));
    private FileChooserField outDirField = new FileChooserField();

    private JLabel kindlegenLabel = new LabelForMandatory(getLocText("gui.kindlegen.path"));
    private FileChooserField kindlegenField = new FileChooserField(false);
    
    private JLabel kindlegenFoundedLabel = new JLabel(Images.getImage(Images.OK));
    
    private LinkLabel getKindlegenLink = new LinkLabel(getLocText("gui.kindlegen.get_from_web"));
    
    private JButton generateButton = new JButton(
            getLocText("gui.kindlegen.generate"), Images.getImage(GEAR));
    
    private JCheckBox c2CheckBox = new JCheckBox(getLocText("gui.kindlegen.c2"));
    
    private KindlegenRunner runner;
            
    // ------
    
    /** */
    public KindlegenPanel() {
        super();
        initComponents();
        initLayout();
        initEventHandlers();
    }
    
    /** */
    private void initComponents() {
        outDirLabel.setLabelFor(outDirField);
        kindlegenLabel.setLabelFor(kindlegenField);

        generateButton.setEnabled(false);

        outDirField.setEditable(false);
        outDirField.setSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        if (Application.OS_IS_WINDOWS) {
            outDirLabel.setText(getLocText("gui.kindlegen.output_dir.windows"));
        }

        getKindlegenLink.setToolTipText(Constants.KINDLEGEN_DOWNLOAD_URL);
    }

    /** */
    private void initLayout() {
        this.setLayout(new MigLayout("",
                "unrel[label]rel[fill,grow]rel[]rel[]rel[]unrel",
                "unrel[]rel[]"));

        this.add(outDirLabel);
        this.add(outDirField, "spanx 3, sgy, wrap 2*para");

        this.add(kindlegenLabel);
        this.add(kindlegenField, "spanx 3, sgy");

        this.add(kindlegenFoundedLabel, "hidemode 0, gapleft rel, split, wrap rel");

        this.add(getKindlegenLink, "hidemode 3, skip, spanx 3, right, growx 0, wrap 0");
        this.add(c2CheckBox, "hidemode 3, skip, wrap 0");
        this.add(new JLabel(), "hidemode 3, skip, wrap 2*para");

        this.add(generateButton, "spanx, center, wrap 2*para");
        
        this.add(statusPanel, "spanx, grow");
    }

    /** */
    private void initEventHandlers() {
        kindlegenField.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                setUpKindlegenField();
                update(true);
            }
        });

        getKindlegenLink.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    GuiUtils.setWaitCursorForAmoment(MainFrame.getInstance());
                    DesktopUtils.openBrowser(KINDLEGEN_DOWNLOAD_URL);
                } catch (MalformedURLException ex) {
                    logger.warning(ex.toString());
                }
            }
        });

        generateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generate();
            }
        });
    }

    @Override
    public void clear() {
        update(true);
    }    
    
    @Override
    public ImageIcon getImageIcon() {
        return IMG_EBOOK;
    }

    @Override
    public String getTitle() {
        return getLocText("gui.maintabpane.kindlegen");
    }

    @Override
    public void setVisible(boolean aFlag) {
        super.setVisible(aFlag);
        
        if (aFlag == true ) {
            if (runner == null) {
                setUpKindlegenField();
                update(true);
            }
            else if (generateButton.isEnabled()){
                generateButton.requestFocusInWindow();
            }
        }
    }

    /**
     * Předvyplní {@linkplain #kindlegenField}, pokud ještě nebylo 
     * předvyplněno touto metodou.
     *
     * @see Preferences#getKindlegenCmd(java.lang.Class)
     * @see KindlegenRunner#findKindlegenCommand() 
     */
    private void setUpKindlegenField() {
        if (runner == null) {
            logger.fine("");
            
            runner = new KindlegenRunner();
        
            String kindlegenCmd = 
                    Preferences.getKindlegenCmd(this.getClass());
            if (StringUtils.isBlank(kindlegenCmd)) {
                kindlegenCmd = runner.findKindlegenCommand();
            }

            logger.fine("kindlegenCmd = " + kindlegenCmd);
            
            if (! StringUtils.isBlank(kindlegenCmd)) {
                kindlegenField.setText(kindlegenCmd);
            }
            else {
                kindlegenField.setText("");
            }
        }
    }

    /**
     *
     */
    public void generate() {
        boolean isKindlegen = runner.setBaseKindlegenCommand(
                kindlegenField.getSelectedFilePath());
        runner.setC2compress(c2CheckBox.isSelected());

        if (! isKindlegen) {
            return;
        }

        BookState.getMainInstance().setKindlegen(runner);

        GenerateMobiDialog.showDialog();
    }

    /**
     *
     */
    @Override
    public void update() {
        update(false);        
    }
    
    
    /**
     * 
     * @param withKindlegenCmd 
     */
    void update(boolean withKindlegenCmd) {
        updateWorkingDir();
        if (withKindlegenCmd) {
            updateKindlegen();
        }
        updateStatusPanel();
        updateGenerateButtonEnabled();
    }    

    /**
     * Zjistí zda je v {@linkplain #kindlegenField} zadán platný příkaz
     * {@code kindlegen}.
     */
    private boolean isKindlegenSelected() {
        String kindlegenCmd = kindlegenField.getSelectedFilePath();
        boolean isKindlegen = ! StringUtils.isBlank(kindlegenCmd) && 
                ! StringUtils.isBlank(runner.isKindlegenCommand(kindlegenCmd));
                // runner.isKindlegenCommand(kindlegenCmd) = verze kindlegen
        return isKindlegen;
    }
    
    /**
     * Aktualizuje stav {@linkplain #kindlegenField}, podle toho, zda je
     * zadán platný příkaz {@code kindlegen} nebo ne.
     * 
     * @see #isKindlegenSelected() 
     * @see Preferences#putKindlegenCmd(java.lang.Class, java.lang.String)
     */
    private void updateKindlegen() {
        boolean isKindlegen = isKindlegenSelected();
                
        getKindlegenLink.setVisible(! isKindlegen);
        c2CheckBox.setVisible(isKindlegen);
        kindlegenFoundedLabel.setVisible(isKindlegen);
        
        generateButton.setEnabled(isKindlegen);
        
        if (isKindlegen) {
            Preferences.putKindlegenCmd(this.getClass(), 
                    kindlegenField.getSelectedFilePath());
        }
    }
    
    /**
     * 
     */
    private void updateStatusPanel() {
        statusPanel.clear();
        
        if (BookState.getMainInstance().getMetadata() == null) {
            // Nejsou vyplněny povinné položky s informacemi o knize.
            statusPanel.addError(getLocText("gui.kindlegen.status.err_no_metadata"));
        }

        if (BookState.getMainInstance().getBookFiles() == null) {
            // Nejsou určeny potřebné soubory knihy.
            statusPanel.addError(getLocText("gui.kindlegen.status.err_no_bookfiles"));
        }
        
        if (! kindlegenFoundedLabel.isVisible()) {
            // Není zadáno umístění programu kindlegen
            statusPanel.addError(getLocText("gui.kindlegen.status.err_no_kindlegen"));
        }
    }
    
    /**
     * 
     */
    private void updateWorkingDir() {
        outDirField.setSelectedFile(Application.HOME_DIR);
        
        if (BookState.getMainInstance().getBookFiles() != null) {
            String workingDir = BookState.getMainInstance()
                    .getBookFiles().getWorkingDirPath();
            if (! StringUtils.isBlank(workingDir)) {
                outDirField.setSelectedFile(workingDir);
            }            
        }
    }
    
    /**
     * 
     */
    private void updateGenerateButtonEnabled() {
        boolean enabled = BookState.getMainInstance().getMetadata() != null
                && BookState.getMainInstance().getBookFiles() != null
                && kindlegenFoundedLabel.isVisible()
                ;
        
        c2CheckBox.setVisible(enabled);
        generateButton.setEnabled(enabled);
    }
    
}   // KindlegenPanel.java
